import 'dart:math';
import 'dart:ui';

import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_jd/ui/widgets/hero/hero_widget.dart';
import 'package:get/instance_manager.dart';
import 'package:get/route_manager.dart';

typedef DoubleClickAnimationListener = void Function();

// 图片预览
class PictureView extends StatefulWidget {
  final int? arguments;
  final List imgList;
  final int initialPage;
  final Function? onPageChanged;
  final Function? onPageClose;
  final String? heroTag;
  final bool opacity;

  const PictureView({
    Key? key,
    this.arguments,
    this.initialPage = 0,
    required this.imgList,
    this.onPageChanged,
    this.onPageClose,
    this.heroTag,
    this.opacity = false,
  }) : super(key: key);

  @override
  _MyState createState() => _MyState();
}

class _MyState extends State<PictureView> with TickerProviderStateMixin {
  int _currentIndex = 0;
  GlobalKey<ExtendedImageSlidePageState> slidePagekey =
      GlobalKey<ExtendedImageSlidePageState>();
  late AnimationController _doubleClickAnimationController;
  Animation<double>? _doubleClickAnimation;
  late DoubleClickAnimationListener _doubleClickAnimationListener;
  List<double> doubleTapScales = <double>[1.0, 2.0];

  @override
  void initState() {
    _doubleClickAnimationController = AnimationController(
        duration: const Duration(milliseconds: 150), vsync: this);
    super.initState();
    setState(() {
      _currentIndex = widget.initialPage;
    });
  }

  @override
  void dispose() {
    _doubleClickAnimationController.dispose();
    clearGestureDetailsCache();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Widget result = Material(
      color: Colors.transparent,
      shadowColor: Colors.transparent,
      child: Stack(
        fit: StackFit.expand,
        children: <Widget>[
          ExtendedImageGesturePageView.builder(
            controller: PageController(
              initialPage: widget.initialPage,
            ),
            itemBuilder: (BuildContext context, int index) {
              final String imgUrl = widget.imgList[index];

              Widget image = GestureDetector(
                onTap: () {
                  if (widget.onPageClose != null) {
                    widget.onPageClose!();
                  }
                  Get.back();
                },
                child: HeroWidget(
                  tag: widget.heroTag ?? imgUrl,
                  slideType: SlideType.onlyImage,
                  slidePagekey: slidePagekey,
                  opacity: widget.opacity,
                  child: ExtendedImage.network(
                    imgUrl,
                    fit: BoxFit.contain,
                    enableSlideOutPage: true,
                    mode: ExtendedImageMode.gesture,
                    filterQuality: FilterQuality.high,
                    initGestureConfigHandler: (ExtendedImageState state) {
                      double initialScale = 1.0;

                      return GestureConfig(
                        inPageView: true,
                        initialScale: initialScale,
                        maxScale: max(initialScale, 5.0),
                        animationMaxScale: max(initialScale, 5.0),
                        initialAlignment: InitialAlignment.center,
                        cacheGesture: false,
                      );
                    },
                    onDoubleTap: (ExtendedImageGestureState state) {
                      ///you can use define pointerDownPosition as you can,
                      ///default value is double tap pointer down postion.
                      final Offset? pointerDownPosition =
                          state.pointerDownPosition;
                      final double? begin = state.gestureDetails!.totalScale;
                      double end;

                      //remove old
                      _doubleClickAnimation
                          ?.removeListener(_doubleClickAnimationListener);

                      //stop pre
                      _doubleClickAnimationController.stop();

                      //reset to use
                      _doubleClickAnimationController.reset();

                      if (begin == doubleTapScales[0]) {
                        end = doubleTapScales[1];
                      } else {
                        end = doubleTapScales[0];
                      }

                      _doubleClickAnimationListener = () {
                        //print(_animation.value);
                        state.handleDoubleTap(
                            scale: _doubleClickAnimation!.value,
                            doubleTapPosition: pointerDownPosition);
                      };
                      _doubleClickAnimation = _doubleClickAnimationController
                          .drive(Tween<double>(begin: begin, end: end));

                      _doubleClickAnimation!
                          .addListener(_doubleClickAnimationListener);

                      _doubleClickAnimationController.forward();
                    },
                  ),
                ),
              );

              return image;
            },
            onPageChanged: (int index) {
              setState(() {
                _currentIndex = index;
              });
              if (widget.onPageChanged != null) {
                widget.onPageChanged!(index);
              }
            },
            itemCount: widget.imgList.length,
            scrollDirection: Axis.horizontal,
            physics: const BouncingScrollPhysics(),
          ),
          Positioned(
            top: 0,
            right: 0,
            left: 0,
            child: Container(
              width: double.infinity,
              padding: EdgeInsets.only(
                top: MediaQueryData.fromWindow(window).padding.top,
              ),
              alignment: Alignment.center,
              child: Text(
                '${_currentIndex + 1}/${widget.imgList.length}',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 15,
                ),
              ),
            ),
          )
        ],
      ),
    );

    result = ExtendedImageSlidePage(
      key: slidePagekey,
      child: result,
      slideAxis: SlideAxis.both,
      slideType: SlideType.onlyImage,
      resetPageDuration: Duration(milliseconds: 500),
      // 上下滑动背景色
      slidePageBackgroundHandler: (Offset offset, Size pageSize) {
        double opacity = offset.dy.abs() / (pageSize.height / 8);
        return Colors.black.withOpacity(min(1.0, max(1.0 - opacity, 0.0)));
      },
      // 滑动手势关闭触发
      slideEndHandler: (
        Offset offset, {
        ScaleEndDetails? details,
        ExtendedImageSlidePageState? state,
      }) {
        // 下滑关闭页面
        if (offset.dy > 60) {
          return true;
        } else {
          return false;
        }
      },
    );

    return result;
  }
}
